import React, {
  ReactElement,
  useContext,
  useEffect,
  useMemo,
  useState
} from 'react';
import {
  View,
  PanResponder,
  GestureResponderEvent,
  Animated,
  DeviceEventEmitter
} from 'react-native';

import styles from './style';
import { Store } from '../../../../reducer';
import { MARGIN_LEFT, RoundType, ShowToastType } from '../../../../constant';
import { phonePx } from '../../../../../../util/adapt';
import {
  changeBarStatus,
  seekWithTime,
  setClassRoomChangeTime,
  setShowToastType
} from '../../../../actions';
import { CurrentTimeChangeData } from '../../../../types';
import { CLASS_ROOM_EVENT_CURRENT_TIME_CHANGE } from '../../../../event';

let timer: NodeJS.Timer | null;
const ZERO_POSITION = phonePx(140) + MARGIN_LEFT;

const clearTimer = (): void => {
  if (timer) {
    clearTimeout(timer);
    timer = null;
  }
};

export default (): ReactElement => {
  const [contentHeight] = useState(new Animated.Value(phonePx(40)));
  const [classRoomCurrentTime, setClassRoomCurrentTime] = useState<number>(0);

  const { state } = useContext(Store);
  const { classRoomTotalTime, classRoomChangeTime, rounds, showBar } = state;
  const currentTime =
    classRoomChangeTime > -1 ? classRoomChangeTime : classRoomCurrentTime;
  const problemRoundList = rounds.filter(
    (r): boolean => r.roundType === RoundType.Problem
  );

  useEffect((): (() => void) => {
    const subscription = DeviceEventEmitter.addListener(
      CLASS_ROOM_EVENT_CURRENT_TIME_CHANGE,
      (data: CurrentTimeChangeData): void => {
        const { time } = data;
        setClassRoomCurrentTime(time);
      }
    );
    return (): void => {
      if (subscription) {
        subscription.remove();
      }
    };
  }, []);

  let progress = 0;
  if (classRoomTotalTime > 0) {
    progress = currentTime / classRoomTotalTime;
  }

  const dotResponder = PanResponder.create({
    onStartShouldSetPanResponder: (): boolean => true,
    onStartShouldSetPanResponderCapture: (): boolean => true,
    onMoveShouldSetPanResponder: (): boolean => true,
    onMoveShouldSetPanResponderCapture: (): boolean => true,

    onPanResponderGrant: (): void => {
      // onTouch();
      // setTouchMode(true);
    },
    onPanResponderMove: (evt: GestureResponderEvent): void => {
      const { classRoomTotalTime: currentClassRoomTotalTime } = state;
      let moveProgressTime = 0;

      if (evt.nativeEvent.pageX - ZERO_POSITION < 0) {
        // 进度滑动到最左边
        moveProgressTime = 0;
      } else if (evt.nativeEvent.pageX - ZERO_POSITION > phonePx(392)) {
        // 进度滑动到最右边
        moveProgressTime = currentClassRoomTotalTime;
      } else {
        // 在正常区域调整进度
        let moveProgress =
          (evt.nativeEvent.pageX - ZERO_POSITION) / phonePx(392);
        if (moveProgress > 1) {
          moveProgress = 1;
        }
        moveProgressTime = moveProgress * currentClassRoomTotalTime;
      }
      setShowToastType(ShowToastType.PlayProgress);
      setClassRoomChangeTime(moveProgressTime);
      changeBarStatus(true);
    },
    onPanResponderTerminationRequest: (): boolean => true,
    onPanResponderRelease: (): void => {
      const { classRoomChangeTime: currentClassRoomChangeTime } = state;
      seekWithTime(Math.floor(currentClassRoomChangeTime));
      clearTimer();
      timer = setTimeout((): void => {
        setShowToastType(ShowToastType.Unknown);
      }, 1000);
    },
    onShouldBlockNativeResponder: (): boolean => true
  });

  useEffect((): (() => void) => {
    return (): void => {
      clearTimer();
    };
  }, []);

  useEffect((): void => {
    Animated.timing(contentHeight, {
      toValue: showBar ? phonePx(40) : 0,
      duration: 200
    }).start();
  }, [contentHeight, showBar]);

  return useMemo(
    (): ReactElement => (
      <View style={styles.progressContent}>
        <View style={styles.all}>
          <View style={[styles.progress, { width: progress * phonePx(392) }]} />
          {problemRoundList.map(
            (round): ReactElement => {
              const p = round.aboveTotalTime / classRoomTotalTime;
              return (
                <View
                  key={`problemRound-${round.roundId}`}
                  style={[
                    styles.problemDot,
                    { left: p * phonePx(392) - phonePx(2) }
                  ]}
                />
              );
            }
          )}
        </View>
        <Animated.View
          {...dotResponder.panHandlers}
          style={[
            styles.loadDot,
            { left: progress * phonePx(392) - phonePx(40) }
          ]}
        >
          <View style={styles.circle} />
        </Animated.View>
      </View>
    ),
    [classRoomTotalTime, dotResponder.panHandlers, problemRoundList, progress]
  );
};
